﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Globalization;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Shapes;

namespace Gmantis.Controls.Chart
{

    public enum AxisType
    {
        X,
        Y,
        Z
    }

    internal interface IAxis
    {
        // Methods
        void AddLabels(double[] vals, object[] lbls);
        void ClearLabels();
        string Format(double val);
        string Format(object val);
        double FromData(double val);
        int GetAnnoNumber();
        double ToData(double val);

        // Properties
        string AnnoFormat { get; }
        AxisType AxisType { get; }
        bool IsTime { get; }
        double LogBase { get; }
        double MajorUnit { get; }
        double Max { get; set; }
        double Min { get; set; }
        bool Visible { get; set; }
    }

    [EditorBrowsable(EditorBrowsableState.Never), Browsable(false)]
    public class AxisCanvas : Canvas, IAxis
    {
        // Fields
        private UIElement[] _albls;
        private Size _annoSize = new Size();
        internal Axis _axis;
        private Chart _chart;
        private Size _desiredSize = Size.Empty;
        private List<object> _lbls = new List<object>();
        private Rect _lrect = Extensions.EmptyRect;
        internal double _max = double.NaN;
        private double _max0 = double.NaN;
        internal double _min = double.NaN;
        private double _min0 = double.NaN;
        internal Rect _plot = new Rect();
        private Rect _r = Extensions.EmptyRect;
        private double _scale = 1.0;
        private TextBlock _tbtitle;
        internal UIElement[] _ticks;
        private Size _titleDesiredSize = Size.Empty;
        private TransformGroup _trg;
        private RotateTransform _trot;
        private TranslateTransform _trtr;
        private List<double> _vals = new List<double>();
        private const string fmt100pc = "0'%'";
        private const string fmtDate = "d";

        // Methods
        internal AxisCanvas(Axis axis)
        {
            this._axis = axis;
            if (axis != null)
            {
                axis.iax = this;
            }
        }

        void IAxis.AddLabels(double[] vals, object[] lbls)
        {
            if (this._axis.ItemsSource != null)
            {
                this.CreateItemsLabels(this._axis.ItemsSource, false);
            }
            else
            {
                this._vals.AddRange(vals);
                this._lbls.AddRange(lbls);
            }
        }

        void IAxis.ClearLabels()
        {
            this._vals.Clear();
            this._lbls.Clear();
        }

        string IAxis.Format(double val)
        {
            if ((((IAxis)this).LogBase == 2.7182818284590451) && string.IsNullOrEmpty(this._axis.AnnoFormat))
            {
                return ("e" + this.Format(Math.Log(val), "0.##"));
            }
            return this.Format(val, ((IAxis)this).AnnoFormat);
        }

        string IAxis.Format(object val)
        {
            if (!string.IsNullOrEmpty(((IAxis)this).AnnoFormat))
            {
                IFormattable formattable = val as IFormattable;
                if (formattable != null)
                {
                    return formattable.ToString(((IAxis)this).AnnoFormat, null);
                }
            }
            return val.ToString();
        }

        double IAxis.FromData(double val)
        {
            return this.ConvertEx(val);
        }

        int IAxis.GetAnnoNumber()
        {
            if ((this.AnnoSize.Width <= 0.0) || (base.Width <= 0.0))
            {
                return 10;
            }
            int num = (int)(base.Width / this.AnnoSize.Width);
            if (num <= 0)
            {
                num = 1;
            }
            return num;
        }

        double IAxis.ToData(double val)
        {
            double logBase = this._axis.LogBase;
            if (double.IsNaN(logBase))
            {
                if (this.ReversedInternal)
                {
                    if (this._axis.AxisType == AxisType.Y)
                    {
                        return (this._min + (((this._max - this._min) * (val - this._r.Y)) / base.Width));
                    }
                    return (this._min + ((this._max - this._min) * (1.0 - ((val - this._r.X) / base.Width))));
                }
                if (this._axis.AxisType == AxisType.Y)
                {
                    return (this._min + ((this._max - this._min) * (1.0 - ((val - this._r.Y) / base.Width))));
                }
                return (this._min + (((this._max - this._min) * (val - this._r.X)) / base.Width));
            }
            double num2 = 0.0;
            if (this.ReversedInternal)
            {
                if (this._axis.AxisType == AxisType.Y)
                {
                    num2 = (val - this._r.X) / base.Width;
                }
                else
                {
                    num2 = 1.0 - ((val - this._r.Y) / base.Width);
                }
            }
            else if (this._axis.AxisType == AxisType.Y)
            {
                num2 = 1.0 - ((val - this._r.Y) / base.Width);
            }
            else
            {
                num2 = (val - this._r.X) / base.Width;
            }
            return Math.Pow(logBase, Math.Log(this._min, logBase) + ((Math.Log(this._max, logBase) - Math.Log(this._min, logBase)) * num2));
        }

        internal void ClearLabelsAndTicks()
        {
            List<UIElement> list = new List<UIElement>();
            int count = base.Children.Count;
            for (int i = 0; i < count; i++)
            {
                list.Add(base.Children[i]);
            }
            for (int j = 0; j < count; j++)
            {
                if ((list[j] != this.TitleInternal) && (list[j] != this.ScrollBarInternal))
                {
                    base.Children.Remove(list[j]);
                }
            }
        }

        private double Convert(double val)
        {
            if (this._max == this._min)
            {
                return 0.0;
            }
            double logBase = this._axis.LogBase;
            if (double.IsNaN(logBase))
            {
                if (this.ReversedInternal)
                {
                    if (this._axis.AxisType == AxisType.Y)
                    {
                        return (((val - this._min) / (this._max - this._min)) * base.Width);
                    }
                    return (base.Width - (((val - this._min) / (this._max - this._min)) * base.Width));
                }
                if (this._axis.AxisType == AxisType.Y)
                {
                    return (base.Width - (((val - this._min) / (this._max - this._min)) * base.Width));
                }
                return (((val - this._min) / (this._max - this._min)) * base.Width);
            }
            if (val <= 0.0)
            {
                return double.NaN;
            }
            if (this.ReversedInternal)
            {
                if (this._axis.AxisType == AxisType.Y)
                {
                    return ((Math.Log(val / this._min, logBase) / Math.Log(this._max / this._min, logBase)) * base.Width);
                }
                return (base.Width - ((Math.Log(val / this._min, logBase) / Math.Log(this._max / this._min, logBase)) * base.Width));
            }
            if (this._axis.AxisType == AxisType.Y)
            {
                return (base.Width - ((Math.Log(val / this._min, logBase) / Math.Log(this._max / this._min, logBase)) * base.Width));
            }
            return ((Math.Log(val / this._min, logBase) / Math.Log(this._max / this._min, logBase)) * base.Width);
        }

        internal double ConvertEx(double val)
        {
            if (this._axis.AxisType == AxisType.Y)
            {
                return (this._r.Y + this.Convert(val));
            }
            return (this._r.X + this.Convert(val));
        }

        internal virtual UIElement CreateAnno(double val, object lbl)
        {
            if (lbl is UIElement)
            {
                return (UIElement)lbl;
            }
            UIElement el = null;
            if (this.AnnoTemplateInternal is DataTemplate)
            {
                DataTemplate annoTemplateInternal = (DataTemplate)this.AnnoTemplateInternal;
                el = annoTemplateInternal.LoadContent() as UIElement;
                if (el != null)
                {
                    AxisPoint point = new AxisPoint(this.Axis, val, lbl);
                    FrameworkElement element2 = el as FrameworkElement;
                    if (element2 != null)
                    {
                        element2.DataContext = point;
                    }
                }
            }
            if (el == null)
            {
                TextBlock block = new TextBlock();
                if (this._axis.AnnoTemplate is TextBlock)
                {
                    TextBlock annoTemplate = (TextBlock)this._axis.AnnoTemplate;
                    block.Foreground = Utils.Clone(annoTemplate.Foreground);
                }
                else if (this._chart != null)
                {
                    block.Foreground = this._axis.ForegroundInternal;
                }
                string str = "";
                if (lbl is double)
                {
                    str = ((IAxis)this).Format((double)lbl);
                }
                else if (lbl is DateTime)
                {
                    DateTime time = (DateTime)lbl;
                    str = ((IAxis)this).Format(time.ToOADate());
                }
                else
                {
                    str = (lbl != null) ? lbl.ToString() : ((IAxis)this).Format(val);
                }
                block.Text = str;
                el = block;
            }
            this.InitElement(el);
            return el;
        }

        internal void CreateAnnosAndTicks(bool isRadar)
        {
            if (!this._r.IsEmptyRect() && this._axis.Visible)
            {
                double[] vals = this._vals.ToArray();
                object[] itemsAsObjects = this.GetItemsAsObjects();
                int num = (vals != null) ? vals.Length : 0;
                int num2 = (itemsAsObjects != null) ? itemsAsObjects.Length : 0;
                int num3 = Math.Min(num, num2);
                this._albls = new UIElement[num3];
                this._ticks = new UIElement[num3];
                this.CreateMinorTicksAndGrid(vals);
                bool isNear = this.IsNear;
                double majorTickOverlap = this.Axis.MajorTickOverlap;
                bool flag2 = !double.IsNaN(this._axis.LogBase);
                Brush majorGridStroke = this._axis.MajorGridStroke;
                bool inner = (this.Axis.Position & AxisPosition.Inner) > AxisPosition.Near;
                double tickOffset = this.GetTickOffset(inner);
                int num6 = 0;
                Point[] pointArray = null;
                for (int i = num6; i < num3; i++)
                {
                    if ((vals[i] >= this._min) && (vals[i] <= this._max))
                    {
                        if (flag2 && (vals[i] <= 0.0))
                        {
                            continue;
                        }
                        double d = this.Convert(vals[i]);
                        if (double.IsInfinity(d) || double.IsNaN(d))
                        {
                            continue;
                        }
                        UIElement el = (isRadar || (this._axis.AnnoPosition == AnnoPosition.None)) ? null : this.CreateAnno(vals[i], itemsAsObjects[i]);
                        Size size = new Size();
                        if (el != null)
                        {
                            size = Utils.GetSize(el);
                            double annoAngleInternal = this.AnnoAngleInternal;
                            double num10 = 0.0;
                            double num11 = 0.0;
                            Size size2 = size;
                            double num12 = 0.0;
                            double num13 = 1.0;
                            bool flag4 = (inner && isNear) || (!inner && !isNear);
                            if (annoAngleInternal != 0.0)
                            {
                                double a = annoAngleInternal * 0.017453292519943295;
                                num12 = Math.Abs(Math.Sin(a));
                                num13 = Math.Abs(Math.Cos(a));
                                double width = size.Width;
                                double height = size.Height;
                                double num17 = 0.5 * Math.Abs((double)((width * num13) + (height * num12)));
                                double num18 = 0.5 * Math.Abs((double)((width * num12) + (height * num13)));
                                num10 = num18 - (0.5 * height);
                                if (flag4)
                                {
                                    num10 = -num10;
                                }
                                num11 = num17 - (0.5 * width);
                                size.Width = 2.0 * num17;
                                size.Height = 2.0 * num18;
                            }
                            double length = 0.0;
                            if (inner)
                            {
                                length = isNear ? (-((size.Height + tickOffset) + num10) * this._scale) : (((this._r.Height + num10) + tickOffset) * this._scale);
                            }
                            else
                            {
                                length = isNear ? ((tickOffset + num10) * this._scale) : (this._r.Height - (((tickOffset + size.Height) + num10) * this._scale));
                            }
                            Canvas.SetTop(el, length);
                            double num20 = d + num11;
                            if (this._axis.AnnoPosition == AnnoPosition.Auto)
                            {
                                if ((Math.Abs(num12) > 0.01) && (this._axis.AnnoAngle != 0.0))
                                {
                                    double num21 = annoAngleInternal * 0.017453292519943295;
                                    num12 = Math.Sin(num21);
                                    if (this._axis.AxisType == AxisType.X)
                                    {
                                        if (flag4)
                                        {
                                            num12 = -num12;
                                        }
                                        if (num12 > 0.0)
                                        {
                                            num20 -= ((0.5 * size2.Height) * this._scale) * num12;
                                        }
                                        else
                                        {
                                            num20 -= size.Width * this._scale;
                                            num20 -= ((0.5 * size2.Height) * this._scale) * num12;
                                        }
                                    }
                                    else if (this._axis.AxisType == AxisType.Y)
                                    {
                                        num12 = Math.Abs(num12);
                                        if (!flag4)
                                        {
                                            if (this._axis.AnnoAngle > 0.0)
                                            {
                                                num20 -= size.Height * this._scale;
                                                num20 += ((0.5 * size2.Height) * this._scale) * num12;
                                            }
                                            else
                                            {
                                                num20 -= ((0.5 * size2.Height) * this._scale) * num12;
                                            }
                                        }
                                        else if (this._axis.AnnoAngle < 0.0)
                                        {
                                            num20 -= size.Height * this._scale;
                                            num20 += ((0.5 * size2.Height) * this._scale) * num12;
                                        }
                                        else
                                        {
                                            num20 -= ((0.5 * size2.Height) * this._scale) * num12;
                                        }
                                    }
                                }
                                else
                                {
                                    num20 -= (0.5 * size.Width) * this._scale;
                                }
                            }
                            if (this._axis.AnnoPosition == AnnoPosition.Far)
                            {
                                num20 -= size.Width * this._scale;
                            }
                            Canvas.SetLeft(el, num20);
                            if (this._scale != 1.0)
                            {
                                ScaleTransform transform;
                                transform = new ScaleTransform();
                                transform.ScaleX = transform.ScaleY = this._scale;
                                el.RenderTransform = transform;
                            }
                            if (annoAngleInternal != 0.0)
                            {
                                RotateTransform transform2 = new RotateTransform
                                {
                                    Angle = annoAngleInternal,
                                    CenterX = (0.5 * size2.Width) * this._scale,
                                    CenterY = (0.5 * size2.Height) * this._scale
                                };
                                el.RenderTransform = transform2;
                            }
                            if (inner && ((num20 < 0.0) || ((num20 + size.Width) > this._r.Width)))
                            {
                                el = null;
                            }
                            if (((this.Axis.Position & AxisPosition.DisableLastLabelOverflow) > AxisPosition.Near) && ((num20 + size.Width) > this._r.Width))
                            {
                                el = null;
                            }
                            Point[] pointArray2 = null;
                            if ((this.Axis.AnnoVisibility == AnnoVisibility.HideOverlapped) && (el != null))
                            {
                                Point point = new Point(num20 + ((0.5 * size2.Width) * this._scale), length + ((0.5 * size2.Height) * this._scale));
                                pointArray2 = new Point[] { new Point(point.X - (0.5 * size2.Width), point.Y - (0.5 * size2.Height)), new Point(point.X + (0.5 * size2.Width), point.Y - (0.5 * size2.Height)), new Point(point.X + (0.5 * size2.Width), point.Y + (0.5 * size2.Height)), new Point(point.X - (0.5 * size2.Width), point.Y + (0.5 * size2.Height)) };
                                if (annoAngleInternal != 0.0)
                                {
                                    RotateTransform transform3 = new RotateTransform
                                    {
                                        Angle = annoAngleInternal,
                                        CenterX = point.X,
                                        CenterY = point.Y
                                    };
                                    for (int j = 0; j < 4; j++)
                                    {
                                        pointArray2[j] = transform3.Transform(pointArray2[j]);
                                    }
                                }
                                if ((pointArray != null) && this.Intersect(pointArray, pointArray2))
                                {
                                    el = null;
                                }
                            }
                            if (el != null)
                            {
                                AnnoCreatedEventArgs args = new AnnoCreatedEventArgs(this, el, i, vals[i]);
                                this.Axis.FireAnnoCreated(args);
                                if (args.Cancel)
                                {
                                    el = null;
                                }
                                else
                                {
                                    el = args.Label;
                                }
                            }
                            if ((el != null) && !base.Children.Contains(el))
                            {
                                base.Children.Add(el);
                            }
                            if (el != null)
                            {
                                pointArray = pointArray2;
                            }
                            this._albls[i] = el;
                        }
                        Line line = new Line
                        {
                            Stroke = this._axis.MajorTickStroke
                        };
                        if (line.Stroke == null)
                        {
                            line.Stroke = this._axis.ForegroundInternal;
                        }
                        if (line.Stroke == null)
                        {
                            if (this._chart != null)
                            {
                                line.Stroke = this._chart.Foreground;
                            }
                            else
                            {
                                line.Stroke = new SolidColorBrush(Colors.Black);
                            }
                        }
                        line.StrokeThickness = this._axis.MajorTickThickness;
                        line.X1 = line.X2 = d;
                        double num23 = this.MajorTickHeightInternal * this._scale;
                        if (isNear)
                        {
                            line.Y1 = -num23 * majorTickOverlap;
                            line.Y2 = num23 * (1.0 - majorTickOverlap);
                        }
                        else
                        {
                            line.Y1 = this._r.Height - (num23 * (1.0 - majorTickOverlap));
                            line.Y2 = this._r.Height + (num23 * majorTickOverlap);
                        }
                        base.Children.Add(line);
                        this._ticks[i] = line;
                    }
                    if ((((this._axis.MajorGridFill != null) && ((i % 2) == 1)) && ((vals[i - 1] >= this._min) || (vals[i - 1] >= this._min))) && ((vals[i - 1] <= this._max) || (vals[i - 1] <= this._max)))
                    {
                        double num24 = 0.0;
                        double num25 = 0.0;
                        double num26 = 0.0;
                        double num27 = 0.0;
                        if (this._axis.AxisType == AxisType.X)
                        {
                            num24 = this.Convert(Math.Max(vals[i - 1], this._min));
                            num25 = this.Convert(Math.Min(this._max, vals[i]));
                            num26 = this._plot.Top - this._r.Top;
                            num27 = this._plot.Bottom - this._r.Top;
                        }
                        else if (this._axis.AxisType == AxisType.Y)
                        {
                            num24 = this.Convert(vals[i - 1]);
                            num25 = this.Convert(Math.Min(this._max, vals[i]));
                            num26 = ((this._r.Left + ((this._trtr != null) ? this._trtr.X : 0.0)) - this._plot.Left) - this._plot.Width;
                            num27 = num26 + this._plot.Width;
                        }
                        Rectangle element = new Rectangle
                        {
                            Width = Math.Abs((double)(num25 - num24)),
                            Height = Math.Abs((double)(num27 - num26)),
                            Fill = Utils.Clone(this._axis.MajorGridFill)
                        };
                        Canvas.SetLeft(element, Math.Min(num24, num25));
                        Canvas.SetTop(element, Math.Min(num26, num27));
                        base.Children.Add(element);
                    }
                    if ((!isRadar && (vals[i] >= this._min)) && ((vals[i] <= this._max) && (majorGridStroke != null)))
                    {
                        this.DrawGridLine(majorGridStroke, this._axis.MajorGridStrokeThickness, vals[i], isNear, this._axis.MajorGridStrokeDashes);
                    }
                }
            }
        }

        internal void CreateAnnosAndTicksRadar(RadarView rv, AxisCanvas ay)
        {
            if (this._axis.Visible)
            {
                double[] numArray = this._vals.ToArray();
                object[] itemsAsObjects = this.GetItemsAsObjects();
                int num = (numArray != null) ? numArray.Length : 0;
                int num2 = (itemsAsObjects != null) ? itemsAsObjects.Length : 0;
                int num3 = Math.Min(num, num2);
                if (num3 > 0)
                {
                    this._albls = new UIElement[num3];
                    UIElement[] elementArray1 = ay._ticks;
                    double angle = (6.2831853071795862 * (numArray[num3 - 1] - this._min)) / (this._max - this._min);
                    angle = rv.GetAngle(angle);
                    List<Point> list = new List<Point>();
                    bool isPolar = rv.IsPolar;
                    Brush majorGridStroke = ay.Axis.MajorGridStroke;
                    if ((isPolar && (majorGridStroke != null)) && (ay._vals != null))
                    {
                        Path path = new Path
                        {
                            Stroke = majorGridStroke,
                            StrokeThickness = ay.Axis.MajorGridStrokeThickness,
                            StrokeDashArray = Utils.Clone(ay._axis.MajorGridStrokeDashes)
                        };
                        GeometryGroup group = new GeometryGroup();
                        for (int j = 0; j < ay._vals.Count; j++)
                        {
                            double num6 = (rv.Radius * (ay._vals[j] - ay._min)) / (ay._max - ay._min);
                            if (num6 <= rv.Radius)
                            {
                                EllipseGeometry geometry = new EllipseGeometry
                                {
                                    Center = rv.Center,
                                    RadiusX = num6,
                                    RadiusY = num6
                                };
                                group.Children.Add(geometry);
                            }
                        }
                        path.Data = group;
                        base.Children.Add(path);
                    }
                    for (int i = 0; i < num3; i++)
                    {
                        double num8 = (6.2831853071795862 * (numArray[i] - this._min)) / (this._max - this._min);
                        num8 = rv.GetAngle(num8);
                        double cos = Math.Cos(num8);
                        double sin = Math.Sin(num8);
                        bool haslabel = false;
                        if (ay._axis.RadarLabelVisibility == RadarLabelVisibility.All)
                        {
                            haslabel = true;
                        }
                        else if ((ay._axis.RadarLabelVisibility == RadarLabelVisibility.First) && (i == 0))
                        {
                            haslabel = true;
                        }
                        this.CreateYAxis(ay, rv, haslabel, !isPolar, num8, angle, cos, sin);
                        Axis axis = this.GetAxis(i);
                        haslabel = false;
                        if (axis != null)
                        {
                            if (axis.RadarLabelVisibility == RadarLabelVisibility.All)
                            {
                                haslabel = true;
                            }
                            else if (axis.RadarLabelVisibility == RadarLabelVisibility.First)
                            {
                                haslabel = (axis.RadarPointIndices != null) && (axis.RadarPointIndices[0] == i);
                            }
                            this.CreateYAxis((AxisCanvas)axis.iax, rv, haslabel, false, num8, angle, cos, sin);
                        }
                        if ((numArray[i] >= this._min) && (numArray[i] < this._max))
                        {
                            Line line = Utils.Clone(this.Axis.AxisLine);
                            line.X1 = rv.Center.X;
                            line.Y1 = rv.Center.Y;
                            double x = rv.Center.X + (rv.Radius * cos);
                            double y = rv.Center.Y + (rv.Radius * sin);
                            list.Add(new Point(x, y));
                            line.X2 = x;
                            line.Y2 = y;
                            base.Children.Add(line);
                            UIElement element = this.CreateAnno(numArray[i], itemsAsObjects[i]);
                            if (element != null)
                            {
                                base.Children.Add(element);
                                this.PositionLabel(element, x, y, num8);
                            }
                            if (axis != null)
                            {
                                this.CreateYAxisTicks(rv, (AxisCanvas)axis.iax, sin, cos);
                            }
                            else
                            {
                                this.CreateYAxisTicks(rv, ay, sin, cos);
                            }
                        }
                        angle = num8;
                    }
                    if (isPolar)
                    {
                        Path path3 = new Path
                        {
                            Stroke = this._axis.ForegroundInternal,
                            StrokeThickness = ay.Axis.AxisLine.StrokeThickness
                        };
                        GeometryGroup group2 = new GeometryGroup();
                        EllipseGeometry geometry2 = new EllipseGeometry
                        {
                            Center = rv.Center,
                            RadiusX = rv.Radius,
                            RadiusY = rv.Radius
                        };
                        group2.Children.Add(geometry2);
                        path3.Data = group2;
                        base.Children.Add(path3);
                    }
                    else if (list.Count > 2)
                    {
                        Path path5 = new Path();
                        PathGeometry geometry3 = new PathGeometry
                        {
                            Figures = new PathFigureCollection()
                        };
                        PathFigure figure = new PathFigure
                        {
                            IsClosed = true,
                            StartPoint = list[0]
                        };
                        for (int k = 1; k < list.Count; k++)
                        {
                            LineSegment segment = new LineSegment
                            {
                                Point = list[k]
                            };
                            figure.Segments.Add(segment);
                        }
                        geometry3.Figures.Add(figure);
                        path5.Data = geometry3;
                        path5.Stroke = this._axis.ForegroundInternal;
                        base.Children.Add(path5);
                    }
                }
            }
        }

        internal void CreateItemsLabels(IEnumerable source, bool skipConversion)
        {
            IList<KeyValuePair<object, double>> list = source as IList<KeyValuePair<object, double>>;
            if (list != null)
            {
                int count = list.Count;
                for (int i = 0; i < count; i++)
                {
                    KeyValuePair<object, double> pair = list[i];
                    this._lbls.Add(pair.Key);
                    KeyValuePair<object, double> pair2 = list[i];
                    this._vals.Add(pair2.Value);
                }
            }
            else
            {
                IList<KeyValuePair<object, DateTime>> list2 = source as IList<KeyValuePair<object, DateTime>>;
                if (list2 != null)
                {
                    int num3 = list2.Count;
                    for (int j = 0; j < num3; j++)
                    {
                        KeyValuePair<object, DateTime> pair3 = list2[j];
                        this._lbls.Add(pair3.Key);
                        KeyValuePair<object, DateTime> pair4 = list2[j];
                        this._vals.Add(pair4.Value.ToOADate());
                    }
                }
                else
                {
                    int num5 = 0;
                    DataBindingProxy proxy = null;
                    if (this._axis.ItemsLabelBinding != null)
                    {
                        proxy = new DataBindingProxy();
                    }
                    DataBindingProxy proxy2 = null;
                    if (this._axis.ItemsValueBinding != null)
                    {
                        proxy2 = new DataBindingProxy();
                    }
                    foreach (object obj2 in source)
                    {
                        double naN = double.NaN;
                        if (proxy2 != null)
                        {
                            proxy2.DataContext = obj2;
                            if (this._axis.IsTimeInternal(this._chart))
                            {
                                naN = DataSeries.ConvertObjectDateTime(proxy2.GetValue(this._axis.ItemsValueBinding), 2147483647.0);
                            }
                            else
                            {
                                naN = DataSeries.ConvertObjectNumber(proxy2.GetValue(this._axis.ItemsValueBinding), 2147483647.0);
                            }
                        }
                        else if (this._axis.IsTimeInternal(this._chart))
                        {
                            naN = DataSeries.ConvertObjectDateTime(obj2, 2147483647.0);
                        }
                        else
                        {
                            naN = DataSeries.ConvertObjectNumber(obj2, 2147483647.0);
                        }
                        if (((naN == 2147483647.0) || double.IsNaN(naN)) || skipConversion)
                        {
                            naN = double.NaN;
                            this._vals.Add((double)num5);
                        }
                        else
                        {
                            this._vals.Add(naN);
                        }
                        if (proxy != null)
                        {
                            proxy.DataContext = obj2;
                            this._lbls.Add(proxy.GetValue(this._axis.ItemsLabelBinding));
                        }
                        else if (double.IsNaN(naN))
                        {
                            this._lbls.Add(obj2);
                        }
                        else
                        {
                            this._lbls.Add(((IAxis)this).Format(naN));
                        }
                        num5++;
                    }
                }
            }
        }

        internal void CreateLabels(IEnumerable source)
        {
            this.CreateLabels(source, 0.0);
        }

        internal void CreateLabels(IEnumerable source, double delta)
        {
            if (this._axis.ItemsSource != null)
            {
                this.CreateItemsLabels(this._axis.ItemsSource, false);
            }
            else if (source != null)
            {
                this.CreateItemsLabels(source, true);
            }
            else if (!double.IsNaN(this._min) && !double.IsNaN(this._max))
            {
                ValueLabels labels = ValueLabels.Create(this._min, this._max, this, delta);
                ((IAxis)this).AddLabels(labels.Vals, labels.Lbls);
            }
        }

        private void CreateMinorTick(double val, bool near)
        {
            Line line = new Line
            {
                Stroke = this._axis.MinorTickStroke
            };
            if (line.Stroke == null)
            {
                line.Stroke = this._axis.ForegroundInternal;
            }
            if (line.Stroke == null)
            {
                if (this._chart != null)
                {
                    line.Stroke = Utils.Clone(this._chart.Foreground);
                }
                else
                {
                    line.Stroke = new SolidColorBrush(Colors.Black);
                }
            }
            line.StrokeThickness = this._axis.MinorTickThickness;
            line.X1 = line.X2 = this.Convert(val);
            double num = this.MinorTickHeightInternal * this._scale;
            double minorTickOverlap = this.Axis.MinorTickOverlap;
            if (near)
            {
                line.Y1 = -num * minorTickOverlap;
                line.Y2 = num * (1.0 - minorTickOverlap);
            }
            else
            {
                line.Y1 = this._r.Height - (num * (1.0 - minorTickOverlap));
                line.Y2 = this._r.Height + (num * minorTickOverlap);
            }
            base.Children.Add(line);
            Brush minorGridStroke = this._axis.MinorGridStroke;
            if (minorGridStroke != null)
            {
                this.DrawGridLine(minorGridStroke, this._axis.MinorGridStrokeThickness, val, near, this._axis.MinorGridStrokeDashes);
            }
        }

        private void CreateMinorTicksAndGrid(double[] vals)
        {
            if ((this.Axis.ItemsSource == null) || !double.IsNaN(this._axis.MinorUnit))
            {
                int length = vals.Length;
                bool isNear = this.IsNear;
                if (length >= 1)
                {
                    double unit = 0.0;
                    if (double.IsNaN(this._axis.LogBase))
                    {
                        if (length > 1)
                        {
                            if (double.IsNaN(this._axis.MinorUnit) || (this._axis.MinorUnit <= 0.0))
                            {
                                unit = Math.Round((double)(0.5 * (vals[1] - vals[0])), 15);
                            }
                            else
                            {
                                unit = this._axis.MinorUnit;
                            }
                            if (unit > 0.0)
                            {
                                double num3 = vals[0];
                                while (num3 > this._min)
                                {
                                    num3 -= unit;
                                }
                                double num1 = (this._max - num3) / unit;
                                for (double i = num3; i < this._max; i = Math.Round((double)(i + unit), 14))
                                {
                                    if (i < this._min)
                                    {
                                        continue;
                                    }
                                    bool flag2 = true;
                                    foreach (double num5 in vals)
                                    {
                                        if (Math.Abs((double)(num5 - i)) < (0.01 * unit))
                                        {
                                            flag2 = false;
                                            break;
                                        }
                                    }
                                    if (flag2)
                                    {
                                        this.CreateMinorTick(i, isNear);
                                    }
                                }
                            }
                        }
                    }
                    else
                    {
                        if (double.IsNaN(this._axis.MinorUnit) || (this._axis.MinorUnit <= 0.0))
                        {
                            if (double.IsNaN(((IAxis)this).MajorUnit))
                            {
                                unit = 0.5 * this._axis.LogBase;
                            }
                            else
                            {
                                unit = 0.5 * ((IAxis)this).MajorUnit;
                            }
                        }
                        else
                        {
                            unit = this._axis.MinorUnit;
                        }
                        double[] numArray = ValueLabels.CreateLogarithmicValues(this._min, this._max, unit, this, false);
                        if (numArray != null)
                        {
                            int num6 = numArray.Length;
                            for (int j = 0; j < num6; j++)
                            {
                                if ((Array.BinarySearch<double>(vals, numArray[j]) < 0) && (numArray[j] >= this._min))
                                {
                                    this.CreateMinorTick(numArray[j], isNear);
                                }
                            }
                        }
                    }
                }
            }
        }

        private void CreateYAxis(AxisCanvas ay, RadarView rv, bool haslabel, bool hasGrid, double angle, double angle0, double cos, double sin)
        {
            if (ay._vals != null)
            {
                for (int i = 0; i < ay._vals.Count; i++)
                {
                    if ((ay._vals[i] >= ay._min) && (ay._vals[i] <= ay._max))
                    {
                        double d = (rv.Radius * (ay._vals[i] - ay._min)) / (ay._max - ay._min);
                        if (!double.IsNaN(d))
                        {
                            Point point = new Point(rv.Center.X + (d * cos), rv.Center.Y + (d * sin));
                            Point point2 = new Point(rv.Center.X + (d * Math.Cos(angle0)), rv.Center.Y + (d * Math.Sin(angle0)));
                            if (((d > 0.0) && (d < rv.Radius)) && (hasGrid && (ay.Axis.MajorGridStroke != null)))
                            {
                                Line line = new Line
                                {
                                    Stroke = Utils.Clone(ay._axis.MajorGridStroke),
                                    StrokeThickness = ay._axis.MajorGridStrokeThickness,
                                    StrokeDashArray = Utils.Clone(ay._axis.MajorGridStrokeDashes),
                                    X1 = point2.X,
                                    Y1 = point2.Y,
                                    X2 = point.X,
                                    Y2 = point.Y
                                };
                                base.Children.Add(line);
                            }
                            if (haslabel)
                            {
                                UIElement element = ay.CreateAnno(ay._vals[i], ay._lbls[i]);
                                if (element != null)
                                {
                                    base.Children.Add(element);
                                    this.PositionLabel(element, point.X, point.Y, angle + 1.5707963267948966);
                                }
                            }
                        }
                    }
                }
            }
        }

        private void CreateYAxisTicks(RadarView rv, AxisCanvas ay, double sin, double cos)
        {
            UIElement[] elementArray = ay._ticks;
            if (elementArray != null)
            {
                for (int i = 0; i < elementArray.Length; i++)
                {
                    Line line = elementArray[i] as Line;
                    if (line != null)
                    {
                        Line line2 = Utils.Clone(line);
                        double num2 = Math.Abs((double)(rv.Radius - line.X1));
                        double num3 = rv.Center.X + (num2 * cos);
                        double num4 = rv.Center.Y + (num2 * sin);
                        double num5 = ay.MajorTickHeightInternal * sin;
                        double num6 = ay.MajorTickHeightInternal * cos;
                        line2.X1 = num3 - num5;
                        line2.Y1 = num4 + num6;
                        line2.X2 = num3 + num5;
                        line2.Y2 = num4 - num6;
                        base.Children.Add(line2);
                    }
                }
            }
        }

        private void DrawGridLine(Brush stroke, double thickness, double val, bool near, DoubleCollection dashes)
        {
            double num = 0.0;
            double a = 0.0;
            double num3 = 0.0;
            double num4 = 0.0;
            if (this._axis.AxisType == AxisType.X)
            {
                num = num3 = this.Convert(val);
                a = this._plot.Top - this._r.Top;
                num4 = this._plot.Bottom - this._r.Top;
            }
            else if (this._axis.AxisType == AxisType.Y)
            {
                num = num3 = this.Convert(val);
                a = ((this._r.Left + ((this._trtr != null) ? this._trtr.X : 0.0)) - this._plot.Left) - this._plot.Width;
                num4 = a + this._plot.Width;
            }
            if ((dashes != null) && (dashes.Count > 0))
            {
                Line line = new Line
                {
                    X1 = num,
                    Y1 = a,
                    X2 = num3,
                    Y2 = num4
                };
                line.Stroke = stroke;
                line.StrokeThickness = thickness;
                line.StrokeDashArray = Utils.Clone(dashes);
                base.Children.Add(line);
            }
            else
            {
                Rectangle element = new Rectangle
                {
                    Fill = stroke
                };
                if (this._axis.AxisType == AxisType.X)
                {
                    element.Width = thickness;
                    element.Height = Math.Round(this._plot.Height);
                    Canvas.SetLeft(element, Math.Round((double)(num - (0.5 * thickness))));
                    Canvas.SetTop(element, Math.Round(a));
                }
                else if (this._axis.AxisType == AxisType.Y)
                {
                    element.Width = thickness;
                    element.Height = Math.Round(this._plot.Width);
                    Canvas.SetLeft(element, Math.Round((double)(num - (0.5 * thickness))));
                    Canvas.SetTop(element, a);
                }
                base.Children.Add(element);
            }
        }

        internal string Format(double val, string fmt)
        {
            if (this._axis.IsTimeInternal(this._chart))
            {
                DateTime time = val.FromOADate();
                if (!string.IsNullOrEmpty(fmt) && this._axis.IsValidTimeFmt)
                {
                    return time.ToString(fmt, CultureInfo.CurrentCulture);
                }
                return time.ToString(CultureInfo.CurrentCulture);
            }
            if (!string.IsNullOrEmpty(fmt) && this._axis.IsValidFmt)
            {
                return val.ToString(fmt, CultureInfo.CurrentCulture);
            }
            return val.ToString(CultureInfo.CurrentCulture);
        }

        private Axis GetAxis(int pointIndex)
        {
            foreach (Axis axis in this.Chart.View.Axes)
            {
                if (((axis != this.Chart.View.AxisX) && (axis != this.Chart.View.AxisY)) && (axis.AxisType == AxisType.Y))
                {
                    IList<int> radarPointIndices = axis.RadarPointIndices;
                    if ((radarPointIndices != null) && radarPointIndices.Contains(pointIndex))
                    {
                        return axis;
                    }
                }
            }
            return null;
        }

        private object[] GetItemsAsObjects()
        {
            return this._lbls.ToArray();
        }

        private static Size GetMaxSize(params UIElement[] els)
        {
            Size size = new Size();
            int length = els.Length;
            for (int i = 0; i < length; i++)
            {
                UIElement el = els[i];
                if (el != null)
                {
                    Size size2 = Utils.GetSize(el);
                    if (size2.Width > size.Width)
                    {
                        size.Width = size2.Width;
                    }
                    if (size2.Height > size.Height)
                    {
                        size.Height = size2.Height;
                    }
                }
            }
            return size;
        }

        private Rect GetRect(UIElement ui)
        {
            Size size = Utils.GetSize(ui);
            return new Rect(Canvas.GetLeft(ui), Canvas.GetTop(ui), size.Width, size.Height);
        }

        internal Size GetSize(IEnumerable items, bool isradar)
        {
            Size size = new Size();
            this._annoSize = new Size();
            this._titleDesiredSize = new Size();
            if (this._axis.Visible)
            {
                if (this.TitleInternal != null)
                {
                    if (!base.Children.Contains(this.TitleInternal))
                    {
                        base.Children.Add(this.TitleInternal);
                    }
                    FrameworkElement titleInternal = this.TitleInternal as FrameworkElement;
                    if ((titleInternal != null) && (titleInternal.HorizontalAlignment == HorizontalAlignment.Stretch))
                    {
                        titleInternal.Width = double.NaN;
                    }
                    this._titleDesiredSize = size = Utils.GetSize(this.TitleInternal);
                }
                UIElement scrollBarInternal = this.ScrollBarInternal;
                Size size2 = new Size();
                if ((scrollBarInternal != null) && !isradar)
                {
                    if (!base.Children.Contains(scrollBarInternal))
                    {
                        base.Children.Add(scrollBarInternal);
                    }
                    size2 = Utils.GetSize(scrollBarInternal);
                    size.Height += size2.Height;
                }
                Line axisLine = this._axis.AxisLine;
                if (axisLine == null)
                {
                    axisLine = new Line();
                    this._axis.SetAxisLine(axisLine);
                }
                axisLine.Stroke = this._axis.ForegroundInternal;
                if (axisLine.Stroke == null)
                {
                    axisLine.Stroke = new SolidColorBrush(Colors.Black);
                }
                if (!isradar && !base.Children.Contains(axisLine))
                {
                    base.Children.Add(axisLine);
                }
                this.UpdateAnnosize(items);
                if ((this._axis.Position & AxisPosition.Inner) == AxisPosition.Near)
                {
                    size.Height += this.AnnoSize.Height * this.AnnoRowNum;
                }
                size.Height += this.GetTickOffset(false);
                if (this._axis.AxisType == AxisType.Y)
                {
                    size.Height += 4.0;
                }
            }
            this._desiredSize = size;
            return size;
        }

        private double GetTickOffset(bool inner = false)
        {
            double num = 0.0;
            if (inner)
            {
                num = Math.Max((double)(this.MinorTickHeightInternal * this.Axis.MinorTickOverlap), (double)(this.MajorTickHeightInternal * this.Axis.MajorTickOverlap));
            }
            else
            {
                num = Math.Max((double)(this.MinorTickHeightInternal * (1.0 - this.Axis.MinorTickOverlap)), (double)(this.MajorTickHeightInternal * (1.0 - this.Axis.MajorTickOverlap)));
            }
            if (this._axis.AxisType == AxisType.Y)
            {
                num += 2.0;
            }
            return num;
        }

        private void InitElement(UIElement el)
        {
            if ((this._axis != null) && (this._chart != null))
            {
                TextBlock block = el as TextBlock;
                FontFamily family = this._axis.FontFamily ?? this._chart.FontFamily;
                double num = !double.IsNaN(this._axis.FontSize) ? this._axis.FontSize : this._chart.FontSize;
                FontStretch stretch = (this._axis.ReadLocalValue(Axis.FontStretchProperty) != DependencyProperty.UnsetValue) ? this._axis.FontStretch : this._chart.FontStretch;
                FontStyle style = (this._axis.ReadLocalValue(Axis.FontStyleProperty) != DependencyProperty.UnsetValue) ? this._axis.FontStyle : this._chart.FontStyle;
                FontWeight weight = (this._axis.ReadLocalValue(Axis.FontWeightProperty) != DependencyProperty.UnsetValue) ? this._axis.FontWeight : this._chart.FontWeight;
                if (block != null)
                {
                    SetProperty(block, TextBlock.FontFamilyProperty, family);
                    SetProperty(block, TextBlock.FontSizeProperty, num);
                    SetProperty(block, TextBlock.FontStretchProperty, stretch);
                    SetProperty(block, TextBlock.FontStyleProperty, style);
                    SetProperty(block, TextBlock.FontWeightProperty, weight);
                }
                else
                {
                    Control control = el as Control;
                    if (control != null)
                    {
                        SetProperty(control, Control.FontFamilyProperty, family);
                        SetProperty(control, Control.FontSizeProperty, num);
                        SetProperty(control, Control.FontStretchProperty, stretch);
                        SetProperty(control, Control.FontStyleProperty, style);
                        SetProperty(control, Control.FontWeightProperty, weight);
                    }
                }
            }
        }

        private bool Intersect(Point[] pts1, Point[] pts2)
        {
            return ((Utils.FindIntersection(pts1[0], pts1[1], pts2[1], pts2[2]) != 0) || ((Utils.FindIntersection(pts1[2], pts1[3], pts2[1], pts2[2]) != 0) || ((Utils.FindIntersection(pts1[0], pts1[1], pts2[0], pts2[3]) != 0) || ((Utils.FindIntersection(pts1[2], pts1[3], pts2[0], pts2[3]) != 0) || ((Utils.FindIntersection(pts1[1], pts1[2], pts2[0], pts2[1]) != 0) || ((Utils.FindIntersection(pts1[0], pts1[3], pts2[0], pts2[1]) != 0) || ((Utils.FindIntersection(pts1[1], pts1[2], pts2[2], pts2[3]) != 0) || (Utils.FindIntersection(pts1[0], pts1[3], pts2[2], pts2[3]) != 0))))))));
        }

        internal void Layout(Rect r)
        {
            if (!double.IsNaN(r.Width) && !double.IsNaN(r.Height))
            {
                if ((this.Axis.Position & AxisPosition.OverData) > AxisPosition.Near)
                {
                    Canvas.SetZIndex(this, 1);
                }
                else
                {
                    Canvas.SetZIndex(this, 0);
                }
                if ((this._axis.AxisType == AxisType.Y) && (this._trg == null))
                {
                    this._trot = new RotateTransform();
                    this._trtr = new TranslateTransform();
                    this._trg = new TransformGroup();
                    this._trg.Children.Add(this._trot);
                    this._trg.Children.Add(this._trtr);
                }
                if (this._axis.AxisType != AxisType.Y)
                {
                    this._trg = null;
                }
                this._r = r;
                Canvas.SetLeft(this, r.X);
                Canvas.SetTop(this, r.Y);
                base.Width = r.Width;
                base.Height = r.Height;
                double tickOffset = this.GetTickOffset(false);
                if (!this._axis.Visible || r.IsEmptyRect())
                {
                    if (this.TitleInternal != null)
                    {
                        this.TitleInternal.Visibility = Utils.VisHidden;
                    }
                    if (this._axis.AxisLine != null)
                    {
                        this._axis.AxisLine.Visibility = Utils.VisHidden;
                    }
                }
                else
                {
                    base.Visibility = Visibility.Visible;
                    bool isNear = this.IsNear;
                    if (this._trg != null)
                    {
                        this._trot.Angle = 90.0;
                        this._trtr.X = r.Height;
                        this._trtr.Y = 0.0;
                        base.RenderTransform = this._trg;
                    }
                    else
                    {
                        base.ClearValue(UIElement.RenderTransformProperty);
                    }
                    Line axisLine = this._axis.AxisLine;
                    if (axisLine != null)
                    {
                        axisLine.Visibility = Visibility.Visible;
                        axisLine.X1 = 0.0;
                        axisLine.X2 = r.Width;
                        if (isNear)
                        {
                            axisLine.Y1 = axisLine.Y2 = 0.0;
                        }
                        else
                        {
                            axisLine.Y1 = axisLine.Y2 = r.Height;
                        }
                    }
                    Size size = new Size();
                    if (this.TitleInternal != null)
                    {
                        size = this._titleDesiredSize;
                    }
                    this._scale = 1.0;
                    FrameworkElement scrollBarInternal = this.ScrollBarInternal as FrameworkElement;
                    Size size2 = new Size();
                    if (scrollBarInternal != null)
                    {
                        Thickness scrollBarMargin = this._axis.ScrollBar.ScrollBarMargin;
                        if (isNear)
                        {
                            Canvas.SetTop(scrollBarInternal, tickOffset + this.AnnoSize.Height);
                        }
                        else
                        {
                            Canvas.SetTop(scrollBarInternal, size.Height);
                        }
                        Canvas.SetLeft(scrollBarInternal, scrollBarMargin.Left);
                        scrollBarInternal.Width = (r.Width - scrollBarMargin.Left) - scrollBarMargin.Right;
                        size2 = Utils.GetSize(scrollBarInternal);
                    }
                    if (this.TitleInternal != null)
                    {
                        this.TitleInternal.Visibility = Visibility.Visible;
                        if ((this._axis.AxisType == AxisType.Y) && this.IsNear)
                        {
                            RotateTransform transform = new RotateTransform
                            {
                                Angle = 180.0
                            };
                            this.TitleInternal.RenderTransform = transform;
                            if (this.TitleInternal is TextBlock)
                            {
                                transform.CenterX = 0.5 * size.Width;
                            }
                            else
                            {
                                this.TitleInternal.RenderTransformOrigin = new Point(0.5, 0.5);
                            }
                        }
                        else
                        {
                            this.TitleInternal.RenderTransform = null;
                        }
                        FrameworkElement titleInternal = this.TitleInternal as FrameworkElement;
                        if (titleInternal != null)
                        {
                            switch (titleInternal.HorizontalAlignment)
                            {
                                case HorizontalAlignment.Left:
                                    Canvas.SetLeft(this.TitleInternal, 0.0);
                                    break;

                                case HorizontalAlignment.Center:
                                    Canvas.SetLeft(this.TitleInternal, 0.5 * (r.Width - size.Width));
                                    break;

                                case HorizontalAlignment.Right:
                                    Canvas.SetLeft(this.TitleInternal, r.Width - size.Width);
                                    break;

                                case HorizontalAlignment.Stretch:
                                    {
                                        double width = r.Width;
                                        Thickness margin = titleInternal.Margin;
                                        width -= titleInternal.Margin.Left + titleInternal.Margin.Right;
                                        Canvas.SetLeft(this.TitleInternal, 0.0);
                                        titleInternal.Width = width;
                                        break;
                                    }
                            }
                        }
                        else
                        {
                            Canvas.SetLeft(this.TitleInternal, 0.5 * (r.Width - size.Width));
                        }
                        if (isNear)
                        {
                            if ((this._axis.AxisType == AxisType.Y) && (this.TitleInternal is TextBlock))
                            {
                                Canvas.SetTop(this.TitleInternal, ((tickOffset + this.AnnoSize.Height) + size.Height) + size2.Height);
                            }
                            else
                            {
                                Canvas.SetTop(this.TitleInternal, (tickOffset + this.AnnoSize.Height) + size2.Height);
                            }
                        }
                        else
                        {
                            Canvas.SetTop(this.TitleInternal, 0.0);
                        }
                    }
                }
                this._lrect = r;
            }
        }

        private void PositionLabel(UIElement el, double x, double y, double angle)
        {
            Size size = Utils.GetSize(el);
            Math.Atan2(size.Width, size.Height);
            double num = 0.65 * size.Width;
            double num2 = 0.65 * size.Height;
            double num3 = num * Math.Cos(angle + 3.1415926535897931);
            double num4 = num2 * Math.Sin(angle + 3.1415926535897931);
            x -= 0.5 * size.Width;
            y -= 0.5 * size.Height;
            Canvas.SetLeft(el, x - num3);
            Canvas.SetTop(el, y - num4);
        }

        internal void ResetLimits()
        {
            if (this._axis.AutoMin)
            {
                this.Min0 = this._min = double.NaN;
            }
            else
            {
                this.Min0 = this._min = this._axis.Min;
            }
            if (this._axis.AutoMax)
            {
                this.Max0 = this._max = double.NaN;
            }
            else
            {
                this.Max0 = this._max = this._axis.Max;
            }
        }

        internal void RoundLimits()
        {
            if (!double.IsNaN(this.Max0) && !double.IsNaN(this.Min0))
            {
                if (this.Max0 < this.Min0)
                {
                    double num = this.Max0;
                    this.Max0 = this._axis.Max = this._max = this.Min0;
                    this.Min0 = this._axis.Min = this._min = num;
                }
                if (!double.IsNaN(this._axis.LogBase) && (this.Min0 <= 0.0))
                {
                    this.Min0 = 0.01;
                }
                if (double.IsNegativeInfinity(this.Min0))
                {
                    this.Min0 = -3.4028234663852886E+38;
                }
                if (double.IsPositiveInfinity(this.Max0))
                {
                    this.Max0 = 3.4028234663852886E+38;
                }
                if (!this.Axis.IsDependent && !this.Axis.UseExactLimits)
                {
                    if (this._axis.IsTimeInternal(this._chart))
                    {
                        TimeSpan ts = TimeSpan.FromDays((this.Max0 - this.Min0) / ((double)((IAxis)this).GetAnnoNumber()));
                        TimeSpan span2 = double.IsNaN(((IAxis)this).MajorUnit) ? TimeAxis.NiceTimeSpan(ts, ((IAxis)this).AnnoFormat) : TimeSpan.FromDays(((IAxis)this).MajorUnit);
                        double totalDays = span2.TotalDays;
                        if (this._axis.AutoMin)
                        {
                            double d = TimeAxis.RoundTime(this.Min0, totalDays, false);
                            if ((!double.IsInfinity(d) && !double.IsNaN(d)) && (d < this.Min0))
                            {
                                this.Min0 = d;
                            }
                        }
                        if (this._axis.AutoMax)
                        {
                            double num4 = TimeAxis.RoundTime(this.Max0, totalDays, true);
                            if (num4 < this.Max0)
                            {
                                num4 += totalDays;
                            }
                            if ((!double.IsInfinity(num4) && !double.IsNaN(num4)) && (num4 > this.Max0))
                            {
                                this.Max0 = num4;
                            }
                        }
                    }
                    else
                    {
                        int num5 = Utils.NicePrecision(this.Max0 - this.Min0);
                        if (this._axis.AutoMin && double.IsNaN(this._axis.LogBase))
                        {
                            double num6 = Utils.PrecFloor(-num5, this.Min0);
                            if (!double.IsInfinity(num6) && !double.IsNaN(num6))
                            {
                                this.Min0 = num6;
                            }
                        }
                        if (this._axis.AutoMax && double.IsNaN(this._axis.LogBase))
                        {
                            double num7 = Utils.PrecCeil(-num5, this.Max0);
                            if (!double.IsInfinity(num7) && !double.IsNaN(num7))
                            {
                                this.Max0 = num7;
                            }
                        }
                    }
                }
                if (this._axis.Scale < 1.0)
                {
                    double num8 = (this.Max0 - this.Min0) * this._axis.Scale;
                    this._min = this.Min0 + (this._axis.Value * ((this.Max0 - this.Min0) - num8));
                    this._max = this._min + num8;
                }
                else
                {
                    this._min = this.Min0;
                    this._max = this.Max0;
                }
            }
        }

        internal void SetLimits(double dataMin, double dataMax)
        {
            if (double.IsNaN(this._min))
            {
                this.Min0 = this._min = dataMin;
            }
            if (double.IsNaN(this._max))
            {
                double num = dataMax;
                if (num < this._min)
                {
                    num = this._min + (this._min - num);
                }
                this.Max0 = this._max = num;
            }
            else if ((this._max < this._min) && double.IsNaN(this.Axis.Min))
            {
                this.Min0 = this._min = this._max - (this._min - this._max);
            }
        }

        internal void SetLimitsAux(double dataMin, double dataMax)
        {
            if (double.IsNaN(this.Min0))
            {
                this.Min0 = this._min = dataMin;
            }
            else
            {
                this._min = this.Min0;
            }
            if (double.IsNaN(this.Max0))
            {
                double num = dataMax;
                if (num < this._min)
                {
                    num = (this._min + this._min) - num;
                }
                this.Max0 = this._max = num;
            }
            else
            {
                this._max = this.Max0;
                if ((this._max < this._min) && double.IsNaN(this.Axis.Min))
                {
                    this.Min0 = this._min = this._max - (this._min - this._max);
                }
            }
        }

        private static void SetProperty(DependencyObject obj, DependencyProperty prop, object value)
        {
            if (obj.ReadLocalValue(prop) == DependencyProperty.UnsetValue)
            {
                obj.SetValue(prop, value);
            }
        }

        private void UpdateAnnosize(IEnumerable items)
        {
            if (this._axis.ItemsSource != null)
            {
                items = this._axis.ItemsSource;
            }
            if (items != null)
            {
                List<object> list = new List<object>();
                foreach (object obj2 in items)
                {
                    list.Add(obj2);
                }
                int count = list.Count;
                Size size = new Size(0.0, 0.0);
                for (int i = 0; i < count; i++)
                {
                    object lbl = list[i];
                    if (lbl is KeyValuePair<object, double>)
                    {
                        KeyValuePair<object, double> pair = (KeyValuePair<object, double>)lbl;
                        lbl = pair.Key;
                    }
                    else if (lbl is KeyValuePair<object, DateTime>)
                    {
                        KeyValuePair<object, DateTime> pair2 = (KeyValuePair<object, DateTime>)lbl;
                        lbl = pair2.Key;
                    }
                    Size size2 = Utils.GetSize(this.CreateAnno(0.0, lbl));
                    size.Width = Math.Max(size.Width, size2.Width);
                    size.Height = Math.Max(size.Height, size2.Height);
                }
                this.AnnoSize = size;
            }
            else if (!double.IsNaN(this._min) && !double.IsNaN(this._max))
            {
                UIElement element2;
                UIElement element3;
                double range = this._max - this._min;
                int digits = Utils.NicePrecision(range);
                if ((digits < 0) || (digits > 15))
                {
                    digits = 0;
                }
                double num5 = 0.1 * range;
                if (!double.IsNaN(this._axis.LogBase))
                {
                    element2 = this.CreateAnno(Math.Pow(this._axis.LogBase, Math.Ceiling(Math.Log(this._min, this._axis.LogBase))), null);
                    element3 = this.CreateAnno(Math.Pow(this._axis.LogBase, Math.Floor(Math.Log(this._max, this._axis.LogBase))), null);
                }
                else
                {
                    num5 = Utils.GetMajorUnit(range, this, 0.0);
                    element2 = this.CreateAnno(Math.Round((double)(this._min - num5), digits), null);
                    element3 = this.CreateAnno(Math.Round((double)(this._max + num5), digits), null);
                }
                UIElement element4 = (this._min != this.Min0) ? this.CreateAnno(Math.Round((double)(this.Min0 - num5), digits), null) : null;
                UIElement element5 = (this._max != this.Max0) ? this.CreateAnno(Math.Round((double)(this.Max0 + num5), digits), null) : null;
                this.AnnoSize = GetMaxSize(new UIElement[] { element2, element3, element4, element5 });
            }
        }

        // Properties
        internal double AnnoAngleInternal
        {
            get
            {
                if (this._axis.AxisType != AxisType.Y)
                {
                    return this._axis.AnnoAngle;
                }
                if (this.IsNear)
                {
                    return (this._axis.AnnoAngle - 90.0);
                }
                return (this._axis.AnnoAngle - 90.0);
            }
        }

        internal virtual int AnnoRowNum
        {
            get
            {
                return 1;
            }
        }

        internal Size AnnoSize
        {
            get
            {
                return this._annoSize;
            }
            set
            {
                this._annoSize = value;
                double annoAngleInternal = this.AnnoAngleInternal;
                if (annoAngleInternal != 0.0)
                {
                    annoAngleInternal *= 0.017453292519943295;
                    double num2 = Math.Abs(Math.Sin(annoAngleInternal));
                    double num3 = Math.Abs(Math.Cos(annoAngleInternal));
                    double width = this._annoSize.Width;
                    double height = this._annoSize.Height;
                    this._annoSize.Width = (width * num3) + (height * num2);
                    this._annoSize.Height = (width * num2) + (height * num3);
                }
                if (this.ScrollBarInternal != null)
                {
                    Thickness scrollBarMargin = this._axis.ScrollBar.ScrollBarMargin;
                    this._annoSize.Width = Math.Max(this._annoSize.Width, -scrollBarMargin.Left * 2.0);
                }
            }
        }

        internal object AnnoTemplateInternal
        {
            get
            {
                return this._axis.AnnoTemplate;
            }
        }

        internal Axis Axis
        {
            get
            {
                return this._axis;
            }
            set
            {
                this._axis = value;
                if (this._axis != null)
                {
                    this._axis.iax = this;
                }
            }
        }

        internal string AxisName
        {
            get
            {
                return this._axis.Name;
            }
        }

        internal Rect AxisRect
        {
            get
            {
                Rect rect = this._lrect;
                if (!rect.IsEmptyRect() && (this._axis.AxisType == AxisType.Y))
                {
                    return new Rect(rect.X, rect.Y, rect.Height, rect.Width);
                }
                return rect;
            }
        }

        string IAxis.AnnoFormat
        {
            get
            {
                string annoFormat = this._axis.AnnoFormat;
                if (string.IsNullOrEmpty(annoFormat) && (this._chart != null))
                {
                    if ((this._axis.AxisType == AxisType.Y) && (((this._chart.ChartType == ChartType.ColumnStacked100pc) || (this._chart.ChartType == ChartType.AreaStacked100pc)) || ((this._chart.ChartType == ChartType.LineStacked100pc) || (this._chart.ChartType == ChartType.LineSymbolsStacked100pc))))
                    {
                        annoFormat = "0'%'";
                    }
                    else if ((this._axis.AxisType == AxisType.X) && (this._chart.ChartType == ChartType.BarStacked100pc))
                    {
                        annoFormat = "0'%'";
                    }
                }
                if (string.IsNullOrEmpty(annoFormat) && this._axis.IsTimeInternal(this._chart))
                {
                    annoFormat = TimeAxis.GetTimeDefaultFormat(this._max, this._min);
                }
                if (string.IsNullOrEmpty(annoFormat) && !double.IsNaN(this._axis.LogBase))
                {
                    annoFormat = "G3";
                }
                this._axis.AnnoFormatInternal = annoFormat;
                return annoFormat;
            }
        }

        AxisType IAxis.AxisType
        {
            get
            {
                return this._axis.AxisType;
            }
        }

        bool IAxis.IsTime
        {
            get
            {
                return this._axis.IsTimeInternal(this._chart);
            }
        }

        double IAxis.LogBase
        {
            get
            {
                return this._axis.LogBase;
            }
        }

        double IAxis.MajorUnit
        {
            get
            {
                double majorUnit = this._axis.MajorUnit;
                if (majorUnit <= 0.0)
                {
                    majorUnit = double.NaN;
                }
                return majorUnit;
            }
        }

        double IAxis.Max
        {
            get
            {
                return this._max;
            }
            set
            {
                this._max = value;
            }
        }

        double IAxis.Min
        {
            get
            {
                return this._min;
            }
            set
            {
                this._min = value;
            }
        }

        bool IAxis.Visible
        {
            get
            {
                return this._axis.Visible;
            }
            set
            {
                this._axis.Visible = value;
            }
        }

        internal Chart Chart
        {
            get
            {
                return this._chart;
            }
            set
            {
                this._chart = value;
            }
        }

        internal Size DesiredSize
        {
            get
            {
                return this._desiredSize;
            }
            set
            {
                this._desiredSize = value;
            }
        }

        internal bool IsFar
        {
            get
            {
                return ((this.PositionInternal & AxisPosition.Far) != AxisPosition.Near);
            }
        }

        internal bool IsNear
        {
            get
            {
                return ((this.PositionInternal & AxisPosition.Far) == AxisPosition.Near);
            }
        }

        internal double MajorTickHeightInternal
        {
            get
            {
                return this._axis.MajorTickHeight;
            }
        }

        internal double Max0
        {
            get
            {
                if (!this._axis.AutoMax)
                {
                    return this._axis.Max;
                }
                return this._max0;
            }
            set
            {
                this._max0 = value;
                this._axis.ActualMax = value;
            }
        }

        internal double Min0
        {
            get
            {
                if (!this._axis.AutoMin)
                {
                    return this._axis.Min;
                }
                return this._min0;
            }
            set
            {
                this._min0 = value;
                this._axis.ActualMin = value;
            }
        }

        internal double MinorTickHeightInternal
        {
            get
            {
                return this._axis.MinorTickHeight;
            }
        }

        internal AxisPosition PositionInternal
        {
            get
            {
                return this._axis.Position;
            }
        }

        internal bool ReversedInternal
        {
            get
            {
                return this._axis.Reversed;
            }
        }

        internal UIElement ScrollBarInternal
        {
            get
            {
                IAxisScrollBar scrollBar = this._axis.ScrollBar;
                if ((scrollBar != null) && (scrollBar.ScrollBarPosition != AxisScrollBarPosition.None))
                {
                    return (scrollBar as UIElement);
                }
                return null;
            }
        }

        internal UIElement TitleInternal
        {
            get
            {
                UIElement title = this._axis.Title as UIElement;
                if (title != null)
                {
                    return title;
                }
                if (this._axis.Title != null)
                {
                    string str = this._axis.Title.ToString();
                    if (!string.IsNullOrEmpty(str))
                    {
                        if (this._tbtitle == null)
                        {
                            TextBlock block = new TextBlock
                            {
                                HorizontalAlignment = HorizontalAlignment.Center
                            };
                            this._tbtitle = block;
                            this.InitElement(this._tbtitle);
                        }
                        this._tbtitle.Text = str;
                        return this._tbtitle;
                    }
                }
                return null;
            }
        }
    }

    internal class AxisCanvasCollection : List<Axis>
    {
    }
}
